#include "SWM341.h"

#include "CircleBuffer.h"
#include "synwit_ui_framework/synwit_ui.h"
#include "ui_src/appkit/screens/screen001.h"
#include "swm34s/common/lcdc/dev_lcdc.h"
static CircleBuffer_t CirBuf;


volatile uint32_t      UART_rx_buf_number;   //通讯数据1帧实际大小
volatile uint8_t       UART_rx_buf[50];      //RX数据缓存buffer
volatile uint8_t       myuart_RX_data[14];    //通讯数据
volatile uint8_t	     myuart_RX_enable=1;

//******自定义数据********//


bool shanshuo_flag = false;
uint8_t power_light = 0;
uint8_t system_fault_light = 0;
uint8_t camera_fault_light = 0;
uint8_t sound_state = 0;
uint8_t vision_state = 0;
uint8_t vision_state_temp = 0;
uint8_t vision_delay_count = 0;
bool vision_delay_flag = false;
uint16_t car_speed_state = 0;
uint8_t device_sleep_state = 0;
uint8_t device_turn_state = 0;
//******自定义数据********//

uint8_t show_flag;

void myuart_RX_analysis(void);
  
/**
 * @brief 不使用MicroLIB时避免使用半主机模式
 * 
 */
__asm (".global __use_no_semihosting\n\t");
void _sys_exit(int x)
{
  x = x;
}
/* __use_no_semihosting was requested, but _ttywrch was */
void _ttywrch(int ch)
{
    ch = ch;
}
//struct __FILE
//{
//  int handle;
//};
FILE __stdout;

#if defined ( __GNUC__ ) && !defined (__clang__) 
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif 
PUTCHAR_PROTOTYPE
{
    UART_WriteByte(UART0, ch);

    while (UART_IsTXBusy(UART0))
        ;

    return ch;
}

/*RX数据更新检查 0:无更新  1：有更新*/
uint8_t	update_Check(void)
{
	uint8_t update_tmp=0;

	for(size_t i=0;i<12;i++)			
	{
		if(myuart_RX_data[i] != UART_rx_buf[i+3])
		{
			myuart_RX_data[i]= UART_rx_buf[i+3];
			update_tmp=1;
		}
	}
	return update_tmp;
}

/*RX数据和校验 1：校验通过 0：校验失败 */
uint8_t myuart_RX_check(void)
{
	if ((UART_rx_buf[0]==0x7A)&&(UART_rx_buf[1]==0x09)&&(UART_rx_buf[2]==0x00))
	{
     return 1;
	}
	return 0;
}

void UART0_Handler(void)
{
    uint32_t chr;

    if (UART_INTStat(UART0, UART_IT_RX_THR | UART_IT_RX_TOUT))
    {
        while (UART_IsRXFIFOEmpty(UART0) == 0)
        {
            if (UART_ReadByte(UART0, &chr) == 0)
            {
//                CirBuf_Write(&CirBuf, (uint8_t *)&chr, 1);
                  UART_rx_buf[UART_rx_buf_number++]=(uint8_t)chr;
            }
        }

        if (UART_INTStat(UART0, UART_IT_RX_TOUT))
        {
            UART_INTClr(UART0, UART_IT_RX_TOUT);
            if (myuart_RX_enable&&myuart_RX_check())
            {
                if (update_Check()&&!logo_flag)
                {
                    myuart_RX_analysis();
                }
            }
            // memset(UART_rx_buf,0,UART_rx_buf_number);
            UART_rx_buf_number=0;
        }
    }
}

void uart0_write_buf(uint8_t *buf, uint8_t len)
{
    for (uint32_t i = 0; i < len; i++)
    {
        UART_WriteByte(UART0, buf[i]);
        while (UART_IsTXBusy(UART0))
            ;
    }
}

/* 起始码 数据长度 指令码 数据   CRC码*/
/* 2byte  3byte    1byte  nbytes 2bytes */
/* 定义包头及指令信息 */
#define HEADER0 0xFF // 起始码
#define HEADER1 0x7A // 起始码

/* 枚举读取数据报文的状态 */
typedef enum
{
    FSM_IDLE,
    FSM_HEADER,
    FSM_LEN
} rx_fsm_t;

/* 枚举数据报文的解析状态 */
typedef enum
{
    OK,
    ERROR,
    ERROR_PARA,
    ERROR_NOTSUPPORT,
    ERROR_CRC
} rx_error_t;
/* 定义数据包接收状态的变量,并初始化为空闲状态 */
typedef struct rx
{
    rx_fsm_t fsm;
    rx_error_t error;
    uint8_t len; // 指令参数长度
    uint8_t buf[32];
} rx_t;

static rx_t rx = {FSM_IDLE, OK, 0};


/**
 * @brief uart初始化
 * 
 */
void uart_init(void)
{
    UART_InitStructure UART_initStruct;

    PORT_Init(PORTM, PIN0, PORTM_PIN0_UART0_RX, 1); //GPIOM.0配置为UART0输入引脚
    PORT_Init(PORTM, PIN1, PORTM_PIN1_UART0_TX, 0); //GPIOM.1配置为UART0输出引脚

    UART_initStruct.Baudrate = 115200;
    UART_initStruct.DataBits = UART_DATA_8BIT;
    UART_initStruct.Parity = UART_PARITY_NONE;
    UART_initStruct.StopBits = UART_STOP_1BIT;
    UART_initStruct.RXThreshold = 7;
    UART_initStruct.RXThresholdIEn = 1;
    UART_initStruct.TXThreshold = 3;
    UART_initStruct.TXThresholdIEn = 0;
    UART_initStruct.TimeoutTime = 30;
    UART_initStruct.TimeoutIEn = 1;
    UART_Init(UART0, &UART_initStruct);
    UART_Open(UART0);
    
    CRC_InitStructure CRC_initStruct;
    CRC_initStruct.Poly = CRC_POLY_11021;
    CRC_initStruct.init_crc = 0;
    CRC_initStruct.in_width = CRC_WIDTH_8;
    CRC_initStruct.in_rev = CRC_REV_NOT;
    CRC_initStruct.in_not = false;
    CRC_initStruct.out_rev = CRC_REV_NOT;
    CRC_initStruct.out_not = false;
    CRC_Init(CRC, &CRC_initStruct);
		
		rx.fsm = FSM_IDLE;
}

static unsigned int Rx_CRC_CCITT(unsigned char *puchMsg, unsigned int usDataLen)
{
    CRC_SetInitVal(CRC, 0);
    for(uint32_t i = 0; i < usDataLen; i++)
        CRC_Write(puchMsg[i]);

    return CRC_Result();
}

uint8_t getCheckSum(const uint8_t *pData, int len) {
	int sum = 0;
	for (int i = 0; i < len; ++i) {
		sum += pData[i];
	}
    sum = sum + HEADER0;
    sum = sum + HEADER1;
	//printf("---------- %x ", sum);
	return (uint8_t) sum;
}

static void response_rx(void)
{
    uint8_t tx_buf[] = {0xFF, 0x55, 0x01, 0x00, 0x01, 0x01, 0x00};
    tx_buf[3] = rx.buf[1];
    tx_buf[5] = rx.buf[3];

    uint8_t crc = getCheckSum(&tx_buf[2], 4) ; // 对指令码，序号，指令参数进行crc校验
    tx_buf[7] = crc & 0xFF;

    uart0_write_buf(tx_buf, sizeof(tx_buf));

    rx.fsm = FSM_IDLE;
    memset(rx.buf, 0, sizeof(rx.buf));
}



/*Rx数据解析函数*/
void myuart_RX_analysis(void)
{
    power_light = myuart_RX_data[2+1-3];
    system_fault_light = myuart_RX_data[3+1-3];
    camera_fault_light = myuart_RX_data[4+1-3];
    sound_state = myuart_RX_data[5+1-3];
    vision_state = myuart_RX_data[6+1-3];
	
		if(vision_state_temp!=vision_state)
		{
			if(vision_state!=0)
				vision_state_temp = vision_state;
			
			if(vision_state==0&&!vision_delay_flag)
				vision_delay_flag = true;
		}
  
    if(myuart_RX_data[7+1-3]==0x7B&&myuart_RX_data[8+1-3]==0x01)
    {
      car_speed_state = 0x7B|myuart_RX_data[9+1-3]<<8;
      device_sleep_state = myuart_RX_data[10+1-3];
      device_turn_state = myuart_RX_data[11+1-3];
      //CirBuf_Read(&CirBuf, &receivedbyte, 1);
    }
    else if(myuart_RX_data[7+1-3]==0x7B&&myuart_RX_data[8+1-3]==0x02)
    {
      car_speed_state = 0x7A|myuart_RX_data[9+1-3]<<8;
      device_sleep_state = myuart_RX_data[10+1-3];
      device_turn_state = myuart_RX_data[11+1-3];
      //CirBuf_Read(&CirBuf, &receivedbyte, 1);
    }
    else
    {
      car_speed_state = myuart_RX_data[7+1-3]|myuart_RX_data[8+1-3]<<8;
      device_sleep_state = myuart_RX_data[9+1-3];
      device_turn_state = myuart_RX_data[10+1-3];
    }
    show_flag = 1;
  
		if(sound_state==0)
		{
			//if(key_one_flagA==0&&key_one_flagB==0&&key_one_flagC==0)
				PWM_Stop(PWM1_MSK);
		}
}


void process_rx(void)
{
    if(show_flag)
    {
      ShowPic(1);
      show_flag = 0;
    }
    /*
    uint8_t receivedbyte;
    if (CirBuf_Count(&CirBuf)) // 缓存中有数据
    {
        switch (rx.fsm)
        {
        case FSM_IDLE:
            //CirBuf_Read(&CirBuf, &receivedbyte, 1);
            //if (HEADER0 == receivedbyte)
            //{
                if (CirBuf_Count(&CirBuf))
                {
                    CirBuf_Read(&CirBuf, &receivedbyte, 1);
                    if (HEADER1 == receivedbyte)
                    {
                        rx.fsm = FSM_HEADER;
                    }
                }
            //}
            break;
        case FSM_HEADER:
                if (CirBuf_Count(&CirBuf))
                {
									CirBuf_Read(&CirBuf, rx.buf, 14); // 指令剩余内容
									uint8_t crc = getCheckSum(rx.buf,4); // 对指令码，序号，指令参数进行crc校验

									//if (crc == rx.buf[4])
									{
											power_light = rx.buf[2];
											system_fault_light = rx.buf[3];
											camera_fault_light = rx.buf[4];
											sound_state = rx.buf[5];
											vision_state = rx.buf[6];
										
										if(rx.buf[7]==0x7B&&rx.buf[8]==0x01)
										{
											car_speed_state = 0x7B|rx.buf[9]<<8;
											device_sleep_state = rx.buf[10];
											device_turn_state = rx.buf[11];
											//CirBuf_Read(&CirBuf, &receivedbyte, 1);
										}
										else if(rx.buf[7]==0x7B&&rx.buf[8]==0x02)
										{
											car_speed_state = 0x7A|rx.buf[9]<<8;
											device_sleep_state = rx.buf[10];
											device_turn_state = rx.buf[11];
											//CirBuf_Read(&CirBuf, &receivedbyte, 1);
										}
										else
										{
											car_speed_state = rx.buf[7]|rx.buf[8]<<8;
											device_sleep_state = rx.buf[9];
											device_turn_state = rx.buf[10];
										}
										
											ShowPic(1);
										
											rx.fsm = FSM_IDLE;
									}
								}
            break;
        }
				
    }*/
}
